Skip to content

Add a tutorial to deploy Keycloak in cluster mode#3622

Draft
Frzk wants to merge 15 commits into
masterfrom
feat/keycloak
Draft

Add a tutorial to deploy Keycloak in cluster mode#3622
Frzk wants to merge 15 commits into
masterfrom
feat/keycloak

Conversation

@Frzk

@Frzk Frzk commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@Frzk Frzk self-assigned this Mar 26, 2026
@EtienneM EtienneM self-requested a review March 26, 2026 13:21

@EtienneM EtienneM left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: that's great, I don't have much to say about this :)

Comment thread src/_tutorials/keycloak/index.md Outdated
Comment on lines +72 to +73
This tutorial covers the deployment of Keycloak on Scalingo. Configuring,
managing, and administrating Keycloak is out of the scope of this tutorial.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: add a link to the Keycloak documentations for these?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some in 660662f

Comment thread src/_tutorials/keycloak/index.md Outdated
Comment thread src/_tutorials/keycloak/index.md Outdated
Comment on lines +147 to +151
5. (optional) Create credentials for the initial administrator user:
```bash
scalingo --app my-keycloak env-set KC_BOOTSTRAP_ADMIN_USERNAME=<admin_username>
scalingo --app my-keycloak env-set KC_BOOTSTRAP_ADMIN_PASSWORD=<admin_password>
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: what is the admin password if we don't set this? If it's insecure to not set an admin password, I would mark this step as mandatory

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I've made them mandatory (well they technically aren't but they are if you follow the doc) in c57358e

If the user don't create them, Keycloak will ask them to create one... but the interface is only available on localhost. So it won't work.

Comment thread src/_tutorials/keycloak/index.md Outdated
Comment thread src/_tutorials/keycloak/index.md Outdated
Comment thread src/_tutorials/keycloak/index.md Outdated

- Review the official changelog that is published with each release. Breaking
and notable changes should catch your attention.
- Ensure your SPIs and themes are compatible with the new version.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: what is a SPI?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a link to the little explanation we have in ffd9547

Comment thread src/_tutorials/keycloak/index.md Outdated
Moreover, the buildpack makes use of the following environment variables. They
can be leveraged to customize your deployment:

- `KEYCLOAK_VERSION`\\

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: that makes me think: do we have a NewReleases configuration to track Keycloak releases?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so.
Actually, updating the default version in the buildpack is something I'd like to automate through GitHub Action.
In the meantime, and until it's done, you're right, let's add it :)

@semgrep-code-scalingo

Copy link
Copy Markdown

Legal Risk

The following dependencies were released under a license that
has been flagged by your organization for consideration.

Recommendation

While merging is not directly blocked, it's best to pause and consider what it means to use this license before continuing. If you are unsure, reach out to your security team or Semgrep admin to address this issue.

MPL-2.0

@yanjost yanjost left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One security flag on the nginx sample — happy to chat about the exact Scalingo router CIDR if useful.

charset utf-8;

# Optional hardening:
proxy_hide_header X-Powered-By;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (high — security): this nginx sample doesn't set any X-Forwarded-* headers, but step 5 above mandates KC_PROXY_HEADERS=xforwarded, which tells Keycloak to trust the incoming X-Forwarded-For verbatim for client-IP resolution.

nginx's default is to forward whatever X-Forwarded-For the downstream sent — so a remote client can just set X-Forwarded-For: 8.8.8.8 (rotating values too) and Keycloak will attribute the request to that fake IP. This defeats:

  • the per-IP brute-force / loginFailures counter;
  • realm-level IP allow/deny policies;
  • audit-log forensics on clientAddress;
  • any downstream SIEM rule keyed on Keycloak's reported source IP.

Suggested additions in the server { … } block (around the # Optional hardening: lines):

Suggested change
proxy_hide_header X-Powered-By;
# Optional hardening:
proxy_hide_header X-Powered-By;
# Trust only the Scalingo router for real-IP / XFF rewriting.
# Replace with the documented Scalingo router CIDR(s).
# set_real_ip_from <scalingo-router-CIDR>;
# real_ip_header X-Forwarded-For;
# real_ip_recursive on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;

To verify afterwards: send a request with a forged X-Forwarded-For header, then check clientAddress in the Keycloak admin event log — it should show your real source IP, not the forged one.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

questions:

  • Isn't X-Forwarded-For set by our frontend reverse proxies?
  • If this is a security flaw, shouldn't we better put these settings in our default nginx config file (the one provided by our buildpack)?
  • Can you provide the Scalingo routers CIDRs?

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants